package com.xx.doublexchat.common.websocket.Handler;

import cn.hutool.core.net.url.UrlBuilder;
import com.xx.doublexchat.common.websocket.utils.NettyUtils;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.HttpObject;
import io.netty.handler.codec.http.HttpRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;

import java.net.InetSocketAddress;
import java.util.Optional;

public class MyHeaderCollectHandler extends ChannelInboundHandlerAdapter {
    /**
     * 从Http请求中获取token并放到netty attribute中
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        // 自定义HTTP请求处理
        if (msg instanceof HttpObject) {
            final HttpObject httpObject = (HttpObject) msg;
            if (httpObject instanceof HttpRequest) {
                HttpRequest request = (HttpRequest) msg;
                UrlBuilder urlBuilder = UrlBuilder.ofHttp(request.getUri());
                Optional<String> tokenOptional = Optional.of(urlBuilder)
                        .map(UrlBuilder::getQuery)
                        .map(k -> k.get("token"))//获取token
                        .map(CharSequence::toString);//字符序列化成string
                //判断token是否存在 存在则写入channel中
                tokenOptional.ifPresent(token -> NettyUtils.setAttr(ctx.channel(), NettyUtils.TOKEN, token));
                // 替换request url
                request.setUri(urlBuilder.getPath().toString());
                // 获取用户IP - nginx的ip
                String ip = request.headers().get("X-Real-IP");
                if (StringUtils.isBlank(ip)) {
                    //主机ip
                    InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress();
                    ip = address.getAddress().getHostAddress();
                }
                // 保存到channel --- attribute中
                NettyUtils.setAttr(ctx.channel(), NettyUtils.IP, ip);
                //处理器只需要用一次
                ctx.pipeline().remove(this);
            }
        }
        // 继续其他的解析器
        ctx.fireChannelRead(msg);
    }
}
